package com.JWH_TV

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.view.*
import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.JWH_TV.adapters.ProgramAdapter
import com.JWH_TV.api.domain.ApiResponse
import com.JWH_TV.domain.Program
import com.JWH_TV.`object`.RetrofitInstance
import com.JWH_TV.utils.DecryptUtils
import com.JWH_TV.utils.TokenUtils
import com.bumptech.glide.Glide
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.ui.PlayerView
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.google.android.exoplayer2.upstream.TransferListener

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.net.NetworkInterface
import java.text.SimpleDateFormat
import java.util.*
class MainActivity : AppCompatActivity() {
    private lateinit var drawerLayout: DrawerLayout
    private lateinit var recyclerView: RecyclerView
    private lateinit var tvCategoryName: TextView
    private lateinit var playerView: PlayerView
    private lateinit var loadingLayout: View
    private lateinit var nowPlayingInfoLayout: View
    private lateinit var progressBar: ProgressBar
    private lateinit var exoPlayer: ExoPlayer
    private lateinit var tvChannelName: TextView
    private lateinit var tvNowPlaying: TextView
    private lateinit var tvCurrentTime: TextView
    private lateinit var tvUpcomingProgram: TextView
    private lateinit var tvMacAddress: TextView
    private lateinit var tvAppVersion: TextView
    private lateinit var tvLoadingMessage: TextView
    private lateinit var tvUriId: TextView
    private lateinit var listUnderline: TextView
    private lateinit var tvStop: ImageView
    private lateinit var leftIcon: ImageView
    private var currentSpeedInKB: Long = 0
    private var totalBytesTransferred: Long = 0
    private val categories = mutableListOf<String>()
    private val categoryColors = mutableMapOf<String, String>()
    private var currentCategoryIndex = 0
    private val handler = Handler(Looper.getMainLooper())
    private var isProgramsLoaded = false
    private var playbackStartTime: Long = 0L // 记录播放开始时间
    private var elapsedTimeDuringPlay: Long = 0L // 记录暂停时已播放的时间
    private var totalPausedTime: Long = 0L // 记录总共暂停的时间
    private var isStopScreenVisible = true  // 用于控制暂停画面的显示
    private var isPaused: Boolean = false
    private var isBuffering = false
    private var isFirstPlayer = true
    private var currentProgramIndex = 0  // 当前节目索引
    private var programs: List<Program> = listOf()  // 存储当前类别下的所有节目
    private var isLeftView = false
    var debounceRunnable: Runnable? = null
    val debounceDelay: Long = 750
    private var retryCount = 0
    private val maxRetryCount = 3
    private var isDialogShowing = false
    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        drawerLayout = findViewById(R.id.drawer_layout)
        drawerLayout.setScrimColor(Color.TRANSPARENT)
        recyclerView = findViewById(R.id.recycler_view)
        tvCategoryName = findViewById(R.id.tv_category_name)
        playerView = findViewById(R.id.player_view)
        loadingLayout = findViewById(R.id.loading_layout)
        progressBar = findViewById(R.id.progress_bar)
        tvChannelName = findViewById(R.id.tv_channel_name)
        tvNowPlaying = findViewById(R.id.tv_now_playing)
        tvCurrentTime = findViewById(R.id.tv_current_time)
        tvUpcomingProgram = findViewById(R.id.tv_upcoming_program)
        nowPlayingInfoLayout = findViewById(R.id.now_playing_info_layout)
        tvMacAddress = findViewById(R.id.tv_mac_address)
        tvAppVersion = findViewById(R.id.tv_app_version)
        tvLoadingMessage = findViewById(R.id.tv_loading_message)
        tvUriId = findViewById(R.id.tv_uri_id)
        tvStop = findViewById(R.id.stop_playing)
        leftIcon = findViewById(R.id.left_icon)
        listUnderline = findViewById(R.id.list_underline)
        // 获取mac
        val macAddress = getMacAddresses()
        tvMacAddress.text = "MAC: $macAddress"
        val appVersion = getAppVersion()
        tvAppVersion.text = "Version: $appVersion"
        // 初始化 ExoPlayer
        // 调整缓冲参数以减少延迟
//        val loadControl = DefaultLoadControl.Builder()
//            .setBufferDurationsMs(
//                3000,  // 最小缓冲时间（更激进）
//                4000,  // 最大缓冲时间
//                500,   // 初始缓冲时间
//                500
//            )
//            .setPrioritizeTimeOverSizeThresholds(true)
//            .build()
        exoPlayer = ExoPlayer.Builder(this)
//            .setLoadControl(loadControl)
            .build()

        playerView.player = exoPlayer
        // 设置 RecyclerView
        recyclerView.layoutManager = LinearLayoutManager(this)
        drawerLayout.closeDrawer(Gravity.LEFT)
        // 显示加载界面
        loadingLayout.visibility = View.VISIBLE
        Handler().postDelayed({
            loadPrograms()
        }, 2000)
        drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
                handler.removeCallbacks(closeDrawerRunnable)
                handler.postDelayed(closeDrawerRunnable, 5000)
            }
            override fun onDrawerOpened(drawerView: View) {}
            override fun onDrawerClosed(drawerView: View) {}
            override fun onDrawerStateChanged(newState: Int) {}
        })
    }
    fun animateImageView() {
        val leftIcon = findViewById<ImageView>(R.id.left_icon)
        leftIcon.visibility = View.VISIBLE
        val flipAnimator = ObjectAnimator.ofFloat(leftIcon, "rotationY", 0f, 180f)
        flipAnimator.duration = 8000
        val fadeOutAnimator = ObjectAnimator.ofFloat(leftIcon, "alpha", 1f, 0f)
        fadeOutAnimator.duration = 8000
        val animatorSet = AnimatorSet()
        animatorSet.playTogether(flipAnimator, fadeOutAnimator)
        // 启动动画
        animatorSet.start()
    }
    fun getMacAddresses(): String {
        val startImage = findViewById<ImageView>(R.id.start)
        startImage.visibility = View.VISIBLE
        val macAddressBuilder = StringBuilder()
        try {
            val all = Collections.list(NetworkInterface.getNetworkInterfaces())
            for (nif in all) {
                val name = nif.name
                if (name.equals("wlan0", ignoreCase = true) || name.equals("eth0", ignoreCase = true)) {
                    val macBytes = nif.hardwareAddress ?: continue
                    for (b in macBytes) {
                        macAddressBuilder.append(String.format("%02X", b))
                    }
                }
            }
        } catch (ex: Exception) {
        }
        return if (macAddressBuilder.isNotEmpty()) macAddressBuilder.toString() else "000000000000"
    }
    private fun getAppVersion(): String? {
        try {
            val packageInfo = packageManager.getPackageInfo(packageName, 0)
            return packageInfo.versionName
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return "1.0.0"
    }
    private val closeDrawerRunnable = Runnable {
        if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
            drawerLayout.closeDrawer(Gravity.LEFT)
            isLeftView = false
        }
    }
    private fun loadPrograms() {
        val timestamp = System.currentTimeMillis().toString()
        val token = TokenUtils.generateToken("Tp25076786", timestamp)
        RetrofitInstance.apiService.getLiveList(token, timestamp).enqueue(object : Callback<ApiResponse> {
            override fun onResponse(call: Call<ApiResponse>, response: Response<ApiResponse>) {
                if (response.isSuccessful) {
                    val apiResponse = response.body()
                    if (apiResponse != null && apiResponse.code == 200) {
                        val sortedLiveList = apiResponse.data.sortedBy { channel -> channel.sort }

                        val decryptedPrograms = sortedLiveList.flatMap { channel ->
                            channel.liveList.sortedBy { program -> program.urlId }
                                .map { program ->
                                    decryptProgram(program)
                                }
                        }

                        sortedLiveList.forEach { channel ->
                            categoryColors[channel.typeName] = channel.color
                            categories.add(channel.typeName)
                        }
                        // 初始化节目列表
                        programs = decryptedPrograms
                        if (isFirstPlayer) {
                            // 自动播放第一个节目
                            val firstProgram = decryptedPrograms.firstOrNull()
                            firstProgram?.let {
                                playProgram(it)  // 播放第一个节目
                                currentProgramIndex = 0  // 设置为第一个节目的索引
                            }
                            isFirstPlayer = false
                        }
                        updateCategory()
                        updateProgramList(decryptedPrograms)
                        isProgramsLoaded = true
                        tvAppVersion.visibility = View.GONE
                        tvMacAddress.visibility = View.GONE
                        loadingLayout.visibility = View.GONE
                        drawerLayout.openDrawer(Gravity.LEFT)
                        isLeftView = true
                    } else {
                        Toast.makeText(this@MainActivity, "获取节目数据失败: ${apiResponse?.msg}", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Toast.makeText(this@MainActivity, "获取节目数据失败: ${response.code()}", Toast.LENGTH_SHORT).show()
                }
            }
            override fun onFailure(call: Call<ApiResponse>, t: Throwable) {
                Toast.makeText(this@MainActivity, "网络请求失败: ${t.message}", Toast.LENGTH_SHORT).show()
                tvAppVersion.visibility = View.VISIBLE
                tvMacAddress.visibility = View.VISIBLE
                loadingLayout.visibility = View.VISIBLE
            }
        })
    }
    private fun updateLeftIcon(imageUrl: String?) {
        if (!imageUrl.isNullOrEmpty()) {
            Glide.with(this)
                .load(imageUrl)
                .into(leftIcon)
        } else {
            return
        }
    }
    private fun decryptProgram(program: Program): Program {
        val decryptedUrl = DecryptUtils.decryptUrl(program.url)
        val decryptedPassword = DecryptUtils.decryptPassword(program.password)

        val urlParts = decryptedUrl.split(",")
        val hdStreams = urlParts.filter { it.startsWith("hd") }.map {
            it.substringAfter(":")
        }
        val sdStreams = urlParts.filter { it.startsWith("sd") }.map {
            it.substringAfter(":")
        }

        // 如果 decryptedPassword 为空，则初始化密码列表为空列表
        val passwordParts = if (decryptedPassword.isNotEmpty()) decryptedPassword.split(",") else listOf()
        val hdPasswords = passwordParts.filter { it.startsWith("hd") }.map {
            it.split(":")[1]
        }
        val sdPasswords = passwordParts.filter { it.startsWith("sd") }.map {
            it.split(":")[1]
        }

        // 检查高清流的URL和密码数量是否匹配，如果不匹配且 decryptedPassword 不是空字符串，则抛出异常
        if (hdStreams.size != hdPasswords.size && decryptedPassword.isNotEmpty()) {
            throw IllegalArgumentException("高清流的URL和密码数量不一致")
        }
        program.hdStreams = hdStreams
        program.hdPasswords = hdPasswords

        // 检查标清流的URL和密码数量是否匹配，如果不匹配且 decryptedPassword 不是空字符串，则抛出异常
        if (sdStreams.size != sdPasswords.size && decryptedPassword.isNotEmpty()) {
            throw IllegalArgumentException("标清流的URL和密码数量不一致")
        }
        program.sdStreams = sdStreams
        program.sdPasswords = sdPasswords

        return program
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun updateProgramList(programs: List<Program>) {
        val uniquePrograms = programs.distinctBy { it.name }
        val currentCategoryPrograms = getProgramsForCurrentCategory(uniquePrograms)
        val adapter = ProgramAdapter(currentCategoryPrograms) { program ->
            playProgram(program)
        }
        recyclerView.adapter = adapter
        adapter.notifyDataSetChanged()

        val currentProgramId = getCurrentPlayingProgramId()
        if (currentProgramId != -1) {
            val positionToFocus = currentCategoryPrograms.indexOfFirst { it.urlId == currentProgramId }
            if (positionToFocus != -1) {
                recyclerView.scrollToPosition(positionToFocus)
                adapter.setFocusedPosition(positionToFocus)
            }
        }
    }
    private fun getCurrentPlayingProgramId(): Int {
        return tvUriId.text.toString().toIntOrNull() ?: -1
    }
    private fun getProgramsForCurrentCategory(programList: List<Program>): List<Program> {
        val currentCategory = categories[currentCategoryIndex]
        return programList.filter { it.typeName.contains(currentCategory) }.distinctBy { it.name }
    }
    private fun playProgram(program: Program) {
        // 更新 currentProgramIndex 为当前播放节目的索引
        currentProgramIndex = programs.indexOfFirst { it.urlId == program.urlId }

        val sdPasswordsValid = program.sdPasswords.isNotEmpty() && program.sdPasswords[0].isNotEmpty()
        val hdPasswordsValid = program.hdPasswords.isNotEmpty() && program.hdPasswords[0].isNotEmpty()

        if (sdPasswordsValid || hdPasswordsValid) {
            showPasswordDialog(program)
        } else {
            // 没有密码，直接播放
            resetPlaybackTime()
            tvUriId.text = program.urlId.toString()
            startPlaying(program)
        }
    }
    private fun resetPlaybackTime() {
        playbackStartTime = 0L  // 重置播放开始时间
        elapsedTimeDuringPlay = 0L  // 重置播放过程中的已播放时间
        totalPausedTime = 0L  // 重置暂停时间
        isPaused = false  // 重置暂停状态
        tvStop.visibility = View.GONE  // 隐藏暂停画面
        isStopScreenVisible = false  // 确保暂停画面隐藏
    }

    private fun showPasswordDialog(program: Program) {
        val streamPassword: String? = if (program.liveStream == 1) {
            program.url = program.sdStreams[0]
            program.sdPasswords.getOrNull(0)
        } else {
            program.url = program.hdStreams[0]
            program.hdPasswords.getOrNull(0)
        }

        // 如果密码为 null 或者为空字符串，则直接播放，不弹出密码对话框
        if (streamPassword.isNullOrEmpty() || streamPassword == "null") {
            startPlaying(program)
            return
        }

        // 如果有密码，弹出密码输入框
        val dialogView = layoutInflater.inflate(R.layout.dialog_password, null)
        val channelNameTextView: TextView = dialogView.findViewById(R.id.channel_name)
        val passwordEditText: android.widget.EditText = dialogView.findViewById(R.id.password_edit_text)
        val positiveButton: Button = dialogView.findViewById(R.id.positive_button)
        val negativeButton: Button = dialogView.findViewById(R.id.negative_button)

        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
        channelNameTextView.text = program.name

        val passwordDialog = android.app.AlertDialog.Builder(this)
            .setView(dialogView)
            .create()

        passwordDialog.window?.setDimAmount(0f)  // 去掉背景阴影
        passwordDialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background)

        val width = resources.getDimensionPixelSize(R.dimen.dialog_password_width)
        val height = resources.getDimensionPixelSize(R.dimen.dialog_password_height)
        passwordDialog.window?.setLayout(width, height)

        positiveButton.setOnClickListener {
            val inputPassword = passwordEditText.text.toString()

            // 校验输入的密码
            if (inputPassword == streamPassword) {
                startPlaying(program)
                passwordDialog.dismiss()  // 关闭对话框
            } else {
                Toast.makeText(this, "密碼錯誤", Toast.LENGTH_SHORT).show()
                passwordEditText.setText("") // 清空输入框
                passwordEditText.requestFocus() // 让焦点回到输入框
            }
        }

        negativeButton.setOnClickListener {
            passwordDialog.dismiss()  // 直接关闭对话框
        }

        passwordEditText.setOnKeyListener { _, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN) {
                val inputPassword = passwordEditText.text.toString()

                // 校验输入的密码
                if (inputPassword == streamPassword) {
                    startPlaying(program)
                    passwordDialog.dismiss()  // 关闭对话框
                } else {
                    Toast.makeText(this, "密碼錯誤", Toast.LENGTH_SHORT).show()
                    passwordEditText.setText("") // 清空输入框
                    passwordEditText.requestFocus() // 让焦点回到输入框
                }
                true
            } else {
                false
            }
        }

        passwordDialog.show()
        passwordEditText.requestFocus()
    }

    private fun startPlaying(program: Program) {

        updateLeftIcon(program.image)
        playerView.visibility = View.VISIBLE
        animateImageView()

        // 设置传输监听器以获取下载速度
        val transferListener = object : TransferListener {
            private var startTime: Long = 0
            private var bytesTransferredInSession: Long = 0

            override fun onTransferInitializing(dataSource: DataSource, dataSpec: DataSpec, isNetwork: Boolean) {}

            override fun onTransferStart(dataSource: DataSource, dataSpec: DataSpec, isNetwork: Boolean) {
                startTime = System.currentTimeMillis()
                bytesTransferredInSession = 0
            }

            override fun onBytesTransferred(dataSource: DataSource, dataSpec: DataSpec, isNetwork: Boolean, bytesTransferred: Int) {
                bytesTransferredInSession += bytesTransferred.toLong()
                totalBytesTransferred += bytesTransferred.toLong()

                val elapsedTime = System.currentTimeMillis() - startTime
                if (elapsedTime > 1000) {
                    val speed = (bytesTransferredInSession * 1000) / elapsedTime
                    currentSpeedInKB = speed / 1024
                    startTime = System.currentTimeMillis()
                    bytesTransferredInSession = 0
                }
            }

            override fun onTransferEnd(dataSource: DataSource, dataSpec: DataSpec, isNetwork: Boolean) {
                startTime = 0
                bytesTransferredInSession = 0
            }
        }

        val dataSourceFactory = DefaultHttpDataSource.Factory()
            .setTransferListener(transferListener)

        // 创建 HLS 数据源
        val mediaSource = HlsMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(program.url))

        // 设置播放器并播放
        exoPlayer.setMediaSource(mediaSource)
        exoPlayer.prepare()
        exoPlayer.play()
        playerView.useController = false

        updateNowPlayingInfo(program)

        // 每秒更新加载速度
        val handler = Handler(Looper.getMainLooper())
        val updateRunnable = object : Runnable {
            override fun run() {
                handler.post {
                    tvLoadingMessage.text = "影片加載中...($currentSpeedInKB KB/s)"
                }
                handler.postDelayed(this, 1000)  // 每1秒更新一次
            }
        }
        handler.post(updateRunnable)

        // 播放时间管理
        val playTimeHandler = Handler(Looper.getMainLooper())
        val playTimeRunnable = object : Runnable {
            override fun run() {
                if (playbackStartTime > 0) {
                    val elapsedTime = System.currentTimeMillis() - playbackStartTime
                    if (elapsedTime >= 7200000 && !isPaused) { // 超过2小时
                        exoPlayer.pause()  // 暂停播放
                        tvStop.visibility = View.VISIBLE  // 显示停止画面
                        isPaused = true  // 设置暂停状态
                        elapsedTimeDuringPlay = elapsedTime
                        totalPausedTime += elapsedTime
                    }
                }
                playTimeHandler.postDelayed(this, 1000)  // 每1秒检查一次
            }
        }

        // 监听播放状态变化
        exoPlayer.addListener(object : Player.Listener {
            override fun onPlaybackStateChanged(state: Int) {
                when (state) {
                    Player.STATE_BUFFERING -> {
                        tvLoadingMessage.visibility = View.VISIBLE
                        tvLoadingMessage.text = "影片加載中...($currentSpeedInKB KB/s)"
                        isBuffering = true
                    }
                    Player.STATE_READY -> {
                        tvLoadingMessage.visibility = View.GONE
                        if (playbackStartTime == 0L && !isBuffering && !isPaused) {
                            playbackStartTime = System.currentTimeMillis() - elapsedTimeDuringPlay
                        }
                        isBuffering = false
                    }
                    Player.STATE_IDLE -> {
                        tvLoadingMessage.visibility = View.GONE
                        if (playbackStartTime == 0L && !isBuffering && !isPaused) {
                            playbackStartTime = System.currentTimeMillis() - elapsedTimeDuringPlay
                        }
                        isBuffering = false
                    }
                    Player.STATE_ENDED -> {
                        tvLoadingMessage.visibility = View.GONE
                        if (playbackStartTime == 0L && !isBuffering && !isPaused) {
                            playbackStartTime = System.currentTimeMillis() - elapsedTimeDuringPlay
                        }
                        isBuffering = false
                    }
                }
            }

            override fun onPlayerError(error: PlaybackException) {
//                if (!isBuffering && !isPaused) {
                    handlePlaybackError(program)
//                }
            }
        })

        playTimeHandler.post(playTimeRunnable)
    }

    private fun handlePlaybackError(program: Program) {
            retryPlaying(program)
    }

    private fun showErrorMessageDialog(program: Program) {
        val dialogView = layoutInflater.inflate(R.layout.dialog_error, null)
        val dialog = AlertDialog.Builder(this)
            .setView(dialogView)
            .setCancelable(false)
            .create()
        dialog.window?.setDimAmount(0f)
        dialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background)

        val width = resources.getDimensionPixelSize(R.dimen.dialog_password_width)
        val height = resources.getDimensionPixelSize(R.dimen.dialog_password_height)
        dialog.window?.setLayout(width, height)

        val confirmButton = dialogView.findViewById<Button>(R.id.confirm_button)
        confirmButton.requestFocus()
        confirmButton.setOnClickListener {
            dialog.dismiss()
//            isDialogShowing = false
            retryCount = 0 // 重置重试次数
        }

        dialog.setOnDismissListener {
//            isDialogShowing = false
        }

        dialog.show()
//        isDialogShowing = true

        Log.e("PlaybackError", "播放错误：${program.url}")
    }

    private fun retryPlaying(program: Program) {
        Log.d("RetryPlaying", "Programs list size: ${programs.size}")

        if (retryCount < maxRetryCount) {
            retryCount++
            exoPlayer.stop()
            exoPlayer.clearMediaItems()
            startPlaying(program)
        } else {
            retryCount = 0
            val nextProgram = getNextProgram(program)
            nextProgram?.let { decryptProgram(it) }
            if (nextProgram != null) {
                exoPlayer.stop()
                exoPlayer.clearMediaItems()
                exoPlayer.release() // 释放当前播放器
                initializeExoPlayer() // 重新初始化播放器
                playProgram(nextProgram) // 播放下一个节目
            } else {
                showErrorMessageDialog(program)
            }
        }
    }
    private fun initializeExoPlayer() {
        exoPlayer = ExoPlayer.Builder(this).build()
        playerView.player = exoPlayer
    }

    private fun getNextProgram(currentProgram: Program): Program? {
        val currentIndex = programs.indexOfFirst { it.urlId == currentProgram.urlId }
        return if (currentIndex != -1 && currentIndex < programs.size - 1) {
            val nextProgram = programs[currentIndex + 1]
            Log.d("GetNextProgram", "Next program properties: " +
                    "urlId=${nextProgram.urlId}, " +
                    "url=${nextProgram.url}, " +
                    "image=${nextProgram.image}, "
            )
            nextProgram
        } else {
            null
        }
    }

    private fun updateNowPlayingInfo(program: Program) {
        nowPlayingInfoLayout.visibility = View.VISIBLE
        tvUriId.visibility = View.VISIBLE
        tvChannelName.text = program.name
        tvNowPlaying.text = "正在播放"
        tvCurrentTime.text = getCurrentTime()
        tvUpcomingProgram.text = "即将播放"
        tvUriId.text = program.urlId.toString()
        nowPlayingInfoLayout.postDelayed({
            nowPlayingInfoLayout.visibility = View.GONE
            tvUriId.visibility = View.GONE
        }, 5000)
    }
    private fun getCurrentTime(): String {
        val sdf = SimpleDateFormat("HH:mm", Locale.getDefault())
        return sdf.format(Date())
    }
    override fun onDestroy() {
        super.onDestroy()
        exoPlayer.release()
    }
    @SuppressLint("RtlHardcoded")
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        handler.removeCallbacks(closeDrawerRunnable)
        handler.postDelayed(closeDrawerRunnable, 5000) // 5秒后自动关闭抽屉
        if (tvStop.visibility == View.VISIBLE) {
            elapsedTimeDuringPlay = 0L
            playbackStartTime = System.currentTimeMillis() - elapsedTimeDuringPlay  // 更新播放开始时间为恢复时刻
            totalPausedTime = 0L // 重置暂停时间
            exoPlayer.play()
            tvStop.visibility = View.GONE
            isStopScreenVisible = false  // 确保暂停画面只隐藏一次
            isPaused = false  // 设置为播放状态
            return true
        }

        when (keyCode) {
            KeyEvent.KEYCODE_DPAD_LEFT -> {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    currentCategoryIndex = (currentCategoryIndex - 1 + categories.size) % categories.size
                    currentProgramIndex = 0  // 重置为当前分类的第一个节目索引
                    loadPrograms()
                }
                return true
            }
            KeyEvent.KEYCODE_DPAD_RIGHT -> {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    currentCategoryIndex = (currentCategoryIndex - 1 + categories.size) % categories.size
                    currentProgramIndex = 0  // 重置为当前分类的第一个节目索引
                    loadPrograms()
                }
                return true
            }
            KeyEvent.KEYCODE_DPAD_UP -> {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    if (currentProgramIndex > 0) {
                        currentProgramIndex--
                    }
                    return super.onKeyDown(keyCode, event)
                } else {
                    if (currentProgramIndex > 0) {
                        currentProgramIndex--
                        currentCategoryIndex = categories.indexOf(programs[currentProgramIndex].typeName)
                        updateNowPlayingInfo(programs[currentProgramIndex])
                        debouncePlayProgram()
                    }
                }
                return true
            }

            KeyEvent.KEYCODE_DPAD_DOWN -> {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    if (currentProgramIndex < programs.size - 1) {
                        currentProgramIndex++
                    }
                    return super.onKeyDown(keyCode, event)
                } else {
                    if (currentProgramIndex < programs.size - 1) {
                        currentProgramIndex++
                        currentCategoryIndex = categories.indexOf(programs[currentProgramIndex].typeName)
                        updateProgramListForCurrentCategory()
                        updateNowPlayingInfo(programs[currentProgramIndex])
                        debouncePlayProgram()
                    }
                }
                return true
            }
            KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_DPAD_CENTER -> {
                loadPrograms()
                if (isProgramsLoaded) {
                    drawerLayout.openDrawer(Gravity.LEFT)
                    isLeftView = true
                }
                return true
            }
            KeyEvent.KEYCODE_BACK -> {
                if (drawerLayout.isDrawerOpen(Gravity.LEFT)) {
                    drawerLayout.closeDrawer(Gravity.LEFT)
                }else{
                    showExitDialog()
                }
                return true
            }
            else -> return super.onKeyDown(keyCode, event)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun updateProgramListForCurrentCategory() {
        val currentCategoryPrograms = getProgramsForCurrentCategory2(programs)
        val adapter = ProgramAdapter(currentCategoryPrograms) { program ->
            playProgram(program)
        }
        recyclerView.adapter = adapter
        adapter.notifyDataSetChanged()
        recyclerView.scrollToPosition(currentProgramIndex)
    }

    private fun getProgramsForCurrentCategory2(programList: List<Program>): List<Program> {
        val currentCategory = categories[currentCategoryIndex]
        return programList.filter { it.typeName == currentCategory }
    }

    fun debouncePlayProgram() {
        debounceRunnable?.let { handler.removeCallbacks(it) }

        debounceRunnable = Runnable {
            playProgram(programs[currentProgramIndex])
        }

        handler.postDelayed(debounceRunnable!!, debounceDelay)
    }

    private fun showExitDialog() {
        val context = this
        val dialog = android.app.Dialog(context)
        dialog.setContentView(R.layout.exit_dialog)
        dialog.window?.setDimAmount(0f)
        dialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background)
        val btnCancel: Button = dialog.findViewById(R.id.btn_cancel)
        val btnConfirm: Button = dialog.findViewById(R.id.btn_confirm)
        btnCancel.requestFocus()
        btnCancel.setOnClickListener {
            dialog.dismiss()
        }
        btnConfirm.setOnClickListener {
            dialog.dismiss()
            finish()
        }
        dialog.setOnKeyListener { _, keyCode, event ->
            if (event.action == KeyEvent.ACTION_DOWN) {
                when (keyCode) {
                    KeyEvent.KEYCODE_ENTER -> {
                        if (btnCancel.isFocused) {
                            btnCancel.performClick()
                        } else if (btnConfirm.isFocused) {
                            btnConfirm.performClick()
                        }
                        return@setOnKeyListener true
                    }
                    else -> false
                }
            } else {
                false
            }
        }
        dialog.show()
    }
    private fun updateCategory() {
        val categoryName = categories[currentCategoryIndex]
        val categoryColor = categoryColors[categoryName] ?: "#FFFFFF"
        val displayText = SpannableString("< $categoryName >")
        displayText.setSpan(ForegroundColorSpan(Color.WHITE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        displayText.setSpan(ForegroundColorSpan(Color.WHITE), displayText.length - 1, displayText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        displayText.setSpan(ForegroundColorSpan(Color.parseColor(categoryColor)), 1, displayText.length - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        tvCategoryName.text = displayText
        val underlineView = findViewById<TextView>(R.id.list_underline)
        underlineView.setBackgroundColor(Color.parseColor(categoryColor))
        tvCategoryName.maxLines = 1
        tvCategoryName.ellipsize = TextUtils.TruncateAt.END
        tvCategoryName.setSingleLine(true)
        tvCategoryName.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
    }
}